home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.sources.misc
- organization: York U. Computing Services
- subject: v08i044: explode -- a LaTeX to source-file extracter
- from: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
- Reply-To: davecb@nexus.yorku.ca (David Collier-Brown)
-
- Posting-number: Volume 8, Issue 44
- Submitted-by: davecb@nexus.yorku.ca (David Collier-Brown)
- Archive-name: explode
-
- Well, this is a little program to pull chunks of
- source code out of LaTeX files and put them into one or
- more output files.
- As the man page says, I did this as a simple tool to
- allow better documentation of quite simple programs, ones
- that could be explained easily in a fairly sequential
- discussion. Since it hasn't broken on the few machines
- I've used it on, I'm contributing it to the net. I believe
- it portable and reliable, but it's whole life has been in
- the Berzerkly universe...
-
- --dave
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of shell archive."
- # Contents: Makefile RCS README bar.tex explode.1 explode.c foo.tex
- # unexplode
- # Wrapped by davecb@yunexus on Mon Sep 18 21:50:59 1989
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Makefile'\"
- else
- echo shar: Extracting \"'Makefile'\" \(508 characters\)
- sed "s/^X//" >'Makefile' <<'END_OF_FILE'
- X#
- X# A somewhat generic makefile, for explode
- X#
- XCC=/usr/local/gnu/gcc # Try another compiler
- XSRCS= explode.c
- XOBJS= explode.o
- XCFLAGS= -g
- XDESTDIR= /usr/local/bin
- XMANDIR= /usr/local/man/man1
- X
- Xexplode: ${OBJS}
- X ${CC} -o explode ${CFLAGS} ${OBJS}
- X
- Xinstall:
- X install -s -m 755 explode ${DESTDIR}
- X install -m 755 unexplode ${DESTDIR}
- X cp explode.1 ${MANDIR}/explode.1
- X
- Xdeinstall:
- X rm -f ${DESTDIR}/explode ${DESTDIR}/unexplode
- X rm -f ${MANDIR}/explode.1
- X
- Xclean:
- X rm -f explode *.o core a.out
- Xlint:
- X lint explode.c
- END_OF_FILE
- if test 508 -ne `wc -c <'Makefile'`; then
- echo shar: \"'Makefile'\" unpacked with wrong size!
- fi
- # end of 'Makefile'
- fi
- if test ! -d 'RCS' ; then
- echo shar: Creating directory \"'RCS'\"
- mkdir 'RCS'
- fi
- if test -f 'README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README'\"
- else
- echo shar: Extracting \"'README'\" \(154 characters\)
- sed "s/^X//" >'README' <<'END_OF_FILE'
- XThis is new, incomplet and inefficent.
- X 1) no state in table
- X 2) no error checking
- X 3) no line-splitting when directive in mid-line
- X 4) underdocumented.
- X
- END_OF_FILE
- if test 154 -ne `wc -c <'README'`; then
- echo shar: \"'README'\" unpacked with wrong size!
- fi
- # end of 'README'
- fi
- if test -f 'bar.tex' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'bar.tex'\"
- else
- echo shar: Extracting \"'bar.tex'\" \(136 characters\)
- sed "s/^X//" >'bar.tex' <<'END_OF_FILE'
- X\file{beginning}
- X\begin{verbatim}
- Xbeginning
- X\end{verbatim}
- X
- X\begin{verbatim}
- Xmiddle
- X\end{verbatim}
- X
- X\begin{verbatim}
- Xend
- X\end{verbatim}
- END_OF_FILE
- if test 136 -ne `wc -c <'bar.tex'`; then
- echo shar: \"'bar.tex'\" unpacked with wrong size!
- fi
- # end of 'bar.tex'
- fi
- if test -f 'explode.1' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'explode.1'\"
- else
- echo shar: Extracting \"'explode.1'\" \(1981 characters\)
- sed "s/^X//" >'explode.1' <<'END_OF_FILE'
- X.TH EXPLODE 1
- X.SH NAME
- Xexplode \- file exploder (LaTeX source-code extractor)
- X.SH SYNOPSIS
- X.B explode
- X.I pathname[.tex]
- X.sp
- X.B unexplode
- X.I pathname[.tex]
- X
- X.SH DESCRIPTION
- X.I explode
- Xtakes source code intertwined with LaTeX and emits
- Xjust the code, to however many files as are needed.
- X.I unexplode
- Xdeletes the files created that way.
- X.PP
- XThe syntax of the LaTeX file is very simple:
- X.I \\file{filename}
- Xnames a file to which material will be written.
- X.I \\begin{verbatim}
- Xstarts the copy to the file, and
- X.I \\end{verbatim}
- Xends it.
- X.PP
- XThe verbatim sections can be interleaved with any other
- Xlegal LaTeX construct, and multiple verbatims which
- Xfollow a single \\file directive will be written to the
- Xsame file.
- X.PP
- XMultiple files can be in use at any one time, and
- Xyou can switch between them by inserting a
- X\\file line.
- X
- X.SH EXAMPLE
- XThe following is the simplest plausible explode-file.
- X.nf
- X.nj
- X
- X\\file{foo.h}
- X ...
- X\\begin{verbatim}
- Xtypedef void * FOO;
- X\\end{verbatim}
- X ...
- X\\file{foo.c}
- X\\begin{verbatim}
- X ...
- X.nf
- X.nj
- X
- X.SHISTORY
- XThis was written one afternoon when it became obvious that pr
- Xrewriting my Web subset was going to take a looooong time.
- XThis was written instead, to allow simple, multi-file programs
- Xto be generated from a single LaTeX source file.
- X.PP
- XThe program is extremely simple, has no options and probably never will
- Xhave. The problem of multi-input, multi-output LaTeX ->
- Xprogramming-language coding is not something that's going to succumb
- Xto simple v7 filters. In the meantime, here's the filter.
- X
- XNone at present.
- X
- X.SH SEE ALSO
- XLaTeX(1), tangle(1), weave(1), Donald Knuth's Web system.
- X
- X.SH AUTHORS
- X.nf
- XDave Collier-Brown (davecb@nexus.yorku.ca).
- X.fi
- X
- X.SH DIAGNOSTICS
- X``Too many output files'', if the system runs out of
- Xfile descriptors.
- X
- X.SH BUGS
- XThe limit on output files. An earlier version
- Xre-used file descriptors...
- X.PP
- XThe directives need to be on a line by themselves, as
- Xthe whole line gets discarded after the directive
- Xis interpreted.
- END_OF_FILE
- if test 1981 -ne `wc -c <'explode.1'`; then
- echo shar: \"'explode.1'\" unpacked with wrong size!
- fi
- # end of 'explode.1'
- fi
- if test -f 'explode.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'explode.c'\"
- else
- echo shar: Extracting \"'explode.c'\" \(7384 characters\)
- sed "s/^X//" >'explode.c' <<'END_OF_FILE'
- X/*
- X * explode -- an extact function for a latex-flavored tangle.
- X */
- X#include <stdio.h>
- X#include <strings.h>
- X
- X#define MAXLINE 256
- X#define OK 0
- Xchar *ProgName = NULL;
- Xtypedef enum {NO=0,FILENAME,BEGIN_VERBATIM,END_VERBATIM} KEY;
- X
- X void
- Xmain(argc,argv) int argc; char *argv[]; {
- X int rc = 0, /* Return code from explode. */
- X i;
- X FILE *fp, *lopen();
- X
- X ProgName = argv[0];
- X if (argc < 2 && isatty(0)) {
- X (void) fprintf(stderr,"Usage: %s file[.tex]\n",
- X ProgName);
- X exit(1);
- X }
- X if (!isatty(0)) {
- X rc = explode(stdin);
- X }
- X else {
- X for (i=1; i < argc; i++) {
- X /* printf("argv[%d] = '%s'\n",i,argv[i]); */
- X if ((fp= lopen(argv[i],"r",".tex")) == NULL) {
- X (void) fprintf(stderr,
- X "%s: %s \"%s\", ignored.\n",
- X ProgName, "can't open input file",
- X argv[i]);
- X continue;
- X }
- X else {
- X rc = explode(fp);
- X (void) fclose(fp);
- X }
- X }
- X }
- X exit(rc);
- X}
- X
- X/*
- X * explode -- the main function, which supervises parsing
- X * and output-file bookkeeping.
- X */
- X int
- Xexplode(fp) FILE *fp; {
- X char line[MAXLINE], /* A place to put the line. */
- X operand[MAXLINE]; /* The keyword's parameter. */
- X FILE *outFp, /* Current output file. */
- X *tFp, /* Temporary fp. */
- X *initialFile(), /* Initial output file (/dev/null) */
- X *beginFile(), /* Start writing to taht file. */
- X *endFile(); /* Stop writing to it. */
- X int initiateFile(); /* Associate a name with an fp. */
- X
- X KEY hasKeyWord();
- X
- X if ((outFp= initialFile()) == NULL) {
- X /* Assumed infallible. */
- X (void) fprintf(stderr,"%s: unable to open \"%s\", %s.\n",
- X ProgName,"/dev/null","aborting");
- X exit(3);
- X }
- X while (fgets(line,sizeof(line),fp) != NULL) {
- X switch (hasKeyWord(line,operand)) {
- X case NO: /* Just write the line. */
- X /* printf("body line: %s",line); */
- X (void) fputs(line,outFp);
- X break;
- X case FILENAME: /* Collect a new filename to use. */
- X /* printf("file line: %s, %s",operand,line); */
- X if ( !initiateFile(operand)) {
- X (void) fprintf(stderr,
- X "%s: can't open output file \"%s\", %s.\n",
- X ProgName, operand, "aborting");
- X exit(3);
- X }
- X break;
- X case BEGIN_VERBATIM: /* Start writing to named file. */
- X /* printf("begin line: %s, %s",operand,line); */
- X if ((tFp= beginFile()) != NULL) {
- X outFp = tFp;
- X }
- X else {
- X /* It's "\begin{verbatim}" with no current file. */
- X (void) fputs(line,outFp);
- X }
- X break;
- X case END_VERBATIM: /* Stop writing to that file. */
- X /* printf("end line %s, %s",operand,line); */
- X if ((tFp= endFile()) != NULL) {
- X outFp = tFp;
- X }
- X else {
- X /* It's "\end{verbatim} with no current file". */
- X (void) fputs(line,outFp);
- X }
- X break;
- X }
- X }
- X return OK;
- X}
- X
- X/*
- X * lopen -- local open, sees if there's a file with an optional suffix.
- X */
- X FILE *
- Xlopen(name,mode,ext) char *name, *mode, *ext; {
- X FILE *fp, *fopen();
- X char buffer[MAXLINE],
- X *strcat(), *strcpy();
- X
- X if ((fp= fopen(name,mode)) != NULL) {
- X return fp;
- X }
- X (void) strcat(strcpy(buffer,name),ext);
- X fp = fopen(buffer,mode);
- X return fp;
- X}
- X
- X/*
- X * hasKeyWord -- see if the keyword appears in the line,
- X * return either NO, FILENAME, BEGIN_VERBATIM or END_VERBATIM and
- X * a pointer to a null-terminated string containing
- X * the parameter. Also produces error messages if
- X * the keyword-phrase is misparsed.
- X */
- X#define strchr(s,c) index(s,c)
- X#define streq(s1,s2) (strncmp(s1,s2,strlen(s2))==0)
- X KEY
- XhasKeyWord(line,operand) char *line; char *operand; {
- X register char *p; /* Pointer to current position in string. */
- X KEY rc; /* Result. */
- X char *skipTo();
- X void terminate(), unTerminate();
- X
- X if ((p= strchr(line,'\\')) == NULL) {
- X return NO;
- X }
- X else if (streq(p,"\\file{")) {
- X rc = FILENAME;
- X }
- X else if (streq(line,"\\begin{verbatim}")) {
- X rc = BEGIN_VERBATIM;
- X }
- X else if (streq(line,"\\end{verbatim}")) {
- X rc = END_VERBATIM;
- X }
- X else {
- X return NO;
- X }
- X /* It found one! Stuff "operand" with the parameter value. */
- X p = skipTo(p,'{') + 1;
- X terminate(p,'}');
- X (void) strcpy(operand,p);
- X unTerminate(p,'}');
- X return rc;
- X}
- X
- X/*
- X** string utilities
- X*/
- X char *
- XskipTo(p,c) register char *p; char c; {
- X while (*p && *p != c)
- X p++;
- X return p;
- X }
- X
- X void
- Xterminate(from,at) char *from, at; {
- X while (*from && *from != at)
- X from++;
- X if (!*from)
- X return;
- X *from = '\0';
- X return;
- X}
- X
- X void
- XunTerminate(from,with) char *from, with; {
- X while (*from)
- X from++;
- X *from = with;
- X return;
- X}
- X
- X/*
- X * strsave -- allocate enopugh space for a string & its terminating null.
- X */
- X char *
- Xstrsave(s) char *s; {
- X char *p, *malloc(), *strcpy();
- X
- X if ((p= malloc((unsigned)strlen(s)+1)) != NULL) {
- X return strcpy(p,s);
- X }
- X else {
- X return NULL;
- X }
- X}
- X
- X/*
- X** File -- output-file managment package.
- X** Depends on table package.
- X*/
- X#define CURRENT "The current file"
- Xtypedef struct {
- X char *name;
- X FILE *fp;
- X} TABLE;
- X
- X
- X/*
- X * initialFile -- create the initial output file (/dev/null).
- X */
- X FILE *
- XinitialFile() {
- X FILE *fp, *fopen();
- X TABLE *addToTable();
- X
- X if ((fp= fopen("/dev/null","w")) != NULL
- X && addToTable("/dev/null",fp) != NULL) {
- X return fp;
- X }
- X else {
- X return (FILE *) NULL;
- X }
- X}
- X
- X/*
- X * initiateFile -- get a file pointer for the named file & save it.
- X */
- X int
- XinitiateFile(name) char *name; {
- X TABLE *getFromTable(), *addToTable();
- X FILE *fp, *fopen();
- X
- X if (getFromTable(name) != NULL) {
- X return 1;
- X }
- X else if ((fp= fopen(name,"w")) == NULL) {
- X return 0;
- X }
- X else {
- X return addToTable(name,fp)? 1: 0;
- X }
- X}
- X
- X/*
- X * beginFile -- start writing to that file.
- X */
- X FILE *
- XbeginFile() {
- X TABLE *t, *getFromTable();
- X
- X if ((t= getFromTable(CURRENT)) != NULL) {
- X return t->fp;
- X }
- X else {
- X return NULL;
- X }
- X}
- X
- X/*
- X * endFile -- stop writing to it.
- X */
- X FILE *
- XendFile() {
- X TABLE *getFromTable();
- X
- X if (getFromTable(CURRENT) != NULL) {
- X /* Return the replacement. */
- X return getFromTable("/dev/null")->fp;
- X }
- X else {
- X /* Otherwise don't stop using it. */
- X return (FILE *) NULL;
- X }
- X}
- X
- X
- X/*
- X *
- X */
- X#define NFILES 30
- XTABLE Table[NFILES];
- Xstatic int CurrentFile = -1;
- X
- X TABLE *
- XaddToTable(name,fp) char *name; FILE *fp; {
- X static int lastLookedAt = 0;
- X int i;
- X char *strsave();
- X TABLE *t, *getFromTable();
- X
- X if ((t= getFromTable(name)) != NULL) {
- X return (TABLE *) t;
- X }
- X else {
- X for (i=lastLookedAt; i < NFILES; i++) {
- X if (Table[i].name == NULL) {
- X Table[i].name = strsave(name);
- X Table[i].fp = fp;
- X CurrentFile = i;
- X return &Table[i];
- X }
- X }
- X return (TABLE *) NULL;
- X }
- X}
- X
- X TABLE *
- XgetFromTable(name) char *name; {
- X int i;
- X
- X if (streq(name,CURRENT)) {
- X return (CurrentFile == -1)? (TABLE *) NULL: &Table[CurrentFile];
- X }
- X for (i=0; i < NFILES && Table[i].name != NULL; i++) {
- X if (streq(Table[i].name,name) != NULL) {
- X return &Table[i];
- X }
- X }
- X return (TABLE *) NULL;
- X}
- END_OF_FILE
- if test 7384 -ne `wc -c <'explode.c'`; then
- echo shar: \"'explode.c'\" unpacked with wrong size!
- fi
- # end of 'explode.c'
- fi
- if test -f 'foo.tex' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'foo.tex'\"
- else
- echo shar: Extracting \"'foo.tex'\" \(339 characters\)
- sed "s/^X//" >'foo.tex' <<'END_OF_FILE'
- Xmake explode blow up (run out of file pointers)
- X\file{1}
- X\file{2}
- X\file{3}
- X\file{4}
- X\file{5}
- X\file{6}
- X\file{7}
- X\file{8}
- X\file{9}
- X\file{10}
- X\file{11}
- X\file{12}
- X\file{13}
- X\file{14}
- X\file{15}
- X\file{16}
- X\file{17}
- X\file{18}
- X\file{19}
- X\file{20}
- X\file{21}
- X\file{22}
- X\file{23}
- X\file{24}
- X\file{25}
- X\file{26}
- X\file{27}
- X\file{28}
- X\file{29}
- X\file{30}
- END_OF_FILE
- if test 339 -ne `wc -c <'foo.tex'`; then
- echo shar: \"'foo.tex'\" unpacked with wrong size!
- fi
- # end of 'foo.tex'
- fi
- if test -f 'unexplode' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'unexplode'\"
- else
- echo shar: Extracting \"'unexplode'\" \(341 characters\)
- sed "s/^X//" >'unexplode' <<'END_OF_FILE'
- X#!/bin/sh
- X#
- X# unexplode -- delete the files cerated by explode.
- X#
- Xif [ $# -lt 1 ] ; then
- X echo "unexplode -- delete files created by explode."
- X echo "Usage: unexplode file"
- X exit 1
- Xfi
- Xfor i in $*; do
- X if [ -f $i ] ; then
- X :
- X else
- X if [ -f $i.tex ] ; then
- X i=$i.tex
- X fi
- X fi
- X rm -f `grep '\\file{' $i | sed '
- X s/.file{//
- X s/}//'`
- Xdone
- END_OF_FILE
- if test 341 -ne `wc -c <'unexplode'`; then
- echo shar: \"'unexplode'\" unpacked with wrong size!
- fi
- chmod +x 'unexplode'
- # end of 'unexplode'
- fi
- echo shar: End of shell archive.
- exit 0
-
-
- --
- David Collier-Brown, | davecb@yunexus, ...!yunexus!davecb or
- 72 Abitibi Ave., | {toronto area...}lethe!dave
- Willowdale, Ontario, | Joyce C-B:
- CANADA. 416-223-8968 | He's so smart he's dumb.
-
-